package com.sos.core
{
	import com.sos.utils.ClassUtils;
	
	public class Role
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------		
		
		public static const GOALKEEPER:Role			= new Role(1, "gk", 	"Goalkeeper");
		public static const DEFENSE:Role			= new Role(2, "df", 	"Defence");
		public static const MIDFIELD:Role			= new Role(3, "mf", 	"Midfield");
		public static const FORWARD:Role			= new Role(4, "fw", 	"Forward");
		public static const NONE:Role				= new Role(5, "none",	"None");
		
		// public static const ALL:Role				= new Role(0, "*",		"All");
		public static const ALL:Role				= new Role(0, "any",	"All");
		
		// -------------------------------------------------------------------------------
		// STATIC
		// -------------------------------------------------------------------------------
		
		private static var _initialized:Boolean = false;
		private static var _list:Vector.<Role>;
		
		// Fake static constructor
		{
			// Fill the internal list
			_list = new Vector.<Role>();
			_list.push(Role.GOALKEEPER);
			_list.push(Role.DEFENSE);
			_list.push(Role.MIDFIELD);
			_list.push(Role.FORWARD);
			_list.push(Role.NONE);
			// Init!
			_initialized = true;
		}
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var _id:uint;
		private var _name:String;
		private var _sign:String;
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTORS
		// -------------------------------------------------------------------------------
		
		public function Role(id:uint, sign:String, name:String)
		{
			// Safe unique instance lock
			if (_initialized) throw new Error("Role enum already created!");
			// Init
			_id    = id;
			_name  = name;
			_sign  = sign;
		}

		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------		
		
		public function get id():uint
		{
			return _id;
		}
		
		public function get sign():String
		{
			return _sign;
		}
		
		public function get name():String
		{
			return _name;
		}
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		public function toString():String
		{
			return ClassUtils.getName(this) + "." + _name;
		}
		
		// -------------------------------------------------------------------------------
		// STATIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * Returns the list of the names of 
		 * @return 
		 */
		public static function names(add_all:Boolean=false, add_none:Boolean=true):Array
		{
			var list:Array  = new Array;
			// Add fake ALL items
			if (add_all) list.push(Role.ALL.name);
			// Loop over values list
			for (var i:int=0; i<_list.length; i++)
			{
				if (!add_none && _list[i] == Role.NONE) continue;
				list.push(_list[i].name);
			}
			return list;
		}
		
		/**
		 * 
		 * @return 
		 */
		public static function list(add_all:Boolean=false, add_none:Boolean=true):Array
		{
			var list:Array = new Array;
			// Add fake ALL items
			if (add_all) list.push(Role.ALL);
			// Loop over values list
			for (var i:int=0; i<_list.length; i++)
			{
				if (!add_none && _list[i] == Role.NONE) continue;
				list.push(_list[i]);
			}
			return list;
		}
			
		/**
		 * Search a Role by given id 
		 * @param id Id of the card type to find
		 * @return PlayerRole constant for the given id, null if no Role
		 * for the given id has been found
		 */		
		public static function getById(id:uint):Role
		{
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].id == id) return _list[i];
			}
			throw new Error("Role for id '" + id + "' unknown!");
		}
		
		/**
		 * Search a Role by given name 
		 * @param name Name of the player role to find
		 * @return PlayerRole constant for the given id, null if no Role
		 * for the given name has been found
		 */		
		public static function getByName(name:String):Role
		{
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].name == name) return _list[i];
			}
			throw new Error("Role for name '" + name + "' unknown!");
		}
		
		/**
		 * Search a Role by given sign 
		 * @param name sign of the player role to find
		 * @return PlayerRole constant for the given id, null if no Role
		 * for the given sign has been found
		 */		
		public static function getBySign(sign:String):Role
		{
			// If the sign is NULL, empty or 'none' force the role NONE
			if (sign == null || sign == "" || sign == Role.NONE.sign)
			{
				return Role.NONE;
			}
			// If the sign is 'any', force the role ALL
			if (sign == Role.ALL.sign)
			{
				return Role.ALL;
			}
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].sign == sign) return _list[i];
			}
			throw new Error("Role for sign '" + sign + "' unknown!");
		}

		/**
		 * Retrieves the right role for a PlayerCard by a Position 
		 * @param position
		 * @return 
		 * 
		 */		
		public static function getByPosition(position:Position):Role
		{
			var role:Role = Role.NONE;
			switch (position)
			{
				case Position.GOALKEEPER: 			role = Role.GOALKEEPER; 		break;
				case Position.DEFENDER_01: 			role = Role.DEFENSE; 			break;
				case Position.DEFENDER_02: 			role = Role.DEFENSE; 			break;
				case Position.MIDFIELD: 			role = Role.MIDFIELD; 			break;
				case Position.FORWARD_01: 			role = Role.FORWARD; 			break;
				case Position.FORWARD_02: 			role = Role.FORWARD; 			break;
				case Position.SUB_DEFENCE: 			role = Role.DEFENSE; 			break;
				case Position.SUB_MIDFIELD: 		role = Role.MIDFIELD; 			break;
				case Position.SUB_FORWARD: 			role = Role.FORWARD; 			break;
			}
			return role;
		}
		
	}
}